/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.repair.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.repair.dto.plan.PlanAffairDTO;
import org.springblade.modules.repair.entity.*;
import org.springblade.modules.repair.enums.MaintainPlanContentEnum;
import org.springblade.modules.repair.enums.TaskStatusEnum;
import org.springblade.modules.repair.service.*;
import org.springblade.modules.repair.vo.*;
import org.springblade.modules.repair.mapper.MaintainPlanAffairMapper;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.repair.vo.plan.PlanAffairGroupVO;
import org.springblade.modules.repair.vo.plan.PlanAffairVO;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 事务工单表 服务实现类
 *
 * @author ysq
 * @since 2023-11-14
 */
@AllArgsConstructor
@Service
public class MaintainPlanAffairServiceImpl extends BaseServiceImpl<MaintainPlanAffairMapper, MaintainPlanAffair> implements IMaintainPlanAffairService {

	private final IMaintainPlanContentService maintainPlanContentService;
	private final IMaintainPlanContentUserService maintainPlanContentUserService;
	private final IMaintainMalfunctionHistoryService malfunctionHistoryService;
	private final IMaintainSignService maintainSignService;
	private final IMaintainPlanContentExtService maintainPlanContentExtService;
	private final IMaintainMalfunctionLogService maintainMalfunctionLogService;

	@Override
	public IPage<MaintainPlanAffairVO> selectMaintainPlanAffairPage(IPage<MaintainPlanAffairVO> page, MaintainPlanAffairVO maintainPlanAffair) {
		return page.setRecords(baseMapper.selectMaintainPlanAffairPage(page, maintainPlanAffair));
	}

	@Override
	public PlanAffairDetailVO affairDetail(Long planId) {
		PlanAffairDetailVO detail = baseMapper.selectAffairDetail(planId);
		if (Func.isEmpty(detail)) {
			throw new ServiceException("未找到对应工单");
		}

		// 查询该任务电梯最近一次完成的任务
		LastPlanVO lastPlanVO = maintainPlanContentService.selectElevatorLastPlan(detail.getElevatorId(), planId);
		detail.setLastPlan(lastPlanVO);

		// 查询关联人员信息
		List<MaintainPlanContentUser> planContentUsers = maintainPlanContentUserService.listUserByPlan(planId);
		detail.setPlanContentUsers(planContentUsers);

		// 查询操作记录
		List<MalFunctionHistoryVO> malFunctionHistories = malfunctionHistoryService.selectByPlanId(planId);
		detail.setMalFunctionHistories(malFunctionHistories);

		// 当前用户是否已签到
		Long currentUser = AuthUtil.getUserId();
		List<MaintainSign> list = maintainSignService.list(new LambdaQueryWrapper<MaintainSign>()
			.eq(MaintainSign::getPlanId, planId)
			.eq(MaintainSign::getUserId, currentUser)
		);
		detail.setIsSign(list.size() > 0);

		// 获取当天本人同一台梯是否存在签到记录的签到图片
		ElevatorLastPlanVO lastSignImg = maintainSignService.selectUserLastSignImgByElevator(AuthUtil.getUserId(), detail.getElevatorId());
		detail.setLastSignImg(lastSignImg);

		return detail;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean affairFinish(Long planId) {
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planId);
		if (Func.isEmpty(maintainPlanContent)) {
			throw new ServiceException("未找到对应工单");
		}
		if (maintainPlanContent.getStatus().equals(TaskStatusEnum.SW_SIGN_FINISH.getStatus())) {
			throw new ServiceException("工单状态已变更，请刷新页面");
		}
		if (!maintainPlanContent.getStatus().equals(TaskStatusEnum.SW_UNDER_WAY.getStatus())) {
			throw new ServiceException("工单状态异常，请刷新页面");
		}
		// 查询操作记录
		int historyCount = malfunctionHistoryService.count(Wrappers.<MaintainMalfunctionHistory>lambdaQuery().eq(MaintainMalfunctionHistory::getPlanId, planId));
		if (historyCount == 0) {
			throw new ServiceException("还未添加任务记录，请添加任务记录");
		}

		// 系统代签 任务提交时 未签退人员自动签退
		maintainSignService.checkUserSignOut(planId);

		maintainPlanContent.setStatus(TaskStatusEnum.SW_SIGN_FINISH.getStatus());
		maintainPlanContentService.updateById(maintainPlanContent);
		MaintainPlanContentExt planContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planId));
		long workMinute = DateUtil.between(planContentExt.getPlanBeginTime(), DateUtil.date(), DateUnit.MINUTE);
		planContentExt.setWorkMinute((int) workMinute);
		planContentExt.setPlanEndTime(DateUtil.date());
		maintainPlanContentExtService.updateById(planContentExt);

		maintainPlanContentUserService.updateRescuePlanUserSignInfo(planId);

		// 插入工单记录
		maintainMalfunctionLogService.insertWorkLog(planId, TaskStatusEnum.getTaskName(maintainPlanContent.getTypeStatus(), maintainPlanContent.getStatus()), maintainPlanContent.getStatus());

		return true;
	}

	@Override
	public IPage<PlanAffairVO> list(PlanAffairDTO planAffairDTO) {
		//1:正常,2:签到定位异常,3:签退定位异常，4:系统代签
		Integer[] signTypes = {0, 1, 2, 3, 4};
		Query query = new Query();
		query.setSize(planAffairDTO.getSize());
		query.setCurrent(planAffairDTO.getCurrent());
		IPage<PlanAffairVO> page = Condition.getPage(query);
		//如果电梯id为空表示获取自己的工单
		if (planAffairDTO.getElevatorId() == null) {
			planAffairDTO.setUserId(AuthUtil.getUserId());
		}
		List<PlanAffairVO> list;
		String signSql = "";
		if (planAffairDTO.getSignTypes() != null && planAffairDTO.getSignTypes().size() > 0) {
			for (Integer signType : planAffairDTO.getSignTypes()) {
				if (signType.equals(signTypes[1])) {
					signSql = signSql + "and t8.sign_status = 1 and t8.sign_out_status = 1";
				}
				if (signType.equals(signTypes[2])) {
					signSql = signSql + "and t8.sign_status = 2";
				}
				if (signType.equals(signTypes[3])) {
					signSql = signSql + "and t8.sign_out_status = 2";
				}
				if (signType.equals(signTypes[4])) {
					signSql = signSql + "and t8.status = 2";
				}
			}
			planAffairDTO.setSignSql(signSql);
		}
		if (planAffairDTO.getTypeStatus() == MaintainPlanContentEnum.MAINTAIN_AFFAIR.getId()) {
			list = baseMapper.listBySw(page, planAffairDTO);
		} else if (planAffairDTO.getTypeStatus() == MaintainPlanContentEnum.MAINTAIN_CHECK.getId()) {
			list = baseMapper.listByZj(page, planAffairDTO);
		} else {
			list = baseMapper.listByJy(page, planAffairDTO);
		}
		List<Long> planIds = list.stream().map(PlanAffairVO::getPlanId).collect(Collectors.toList());
		if (planIds.size() > 0) {
			for (PlanAffairVO planAffairVO : list) {
				List<MaintainPlanContentUser> maintainPlanContentUsers = maintainPlanContentUserService.listUserByPlan(planAffairVO.getPlanId());
				planAffairVO.setPlanContentUserVos(maintainPlanContentUsers);
			}
		}
		page.setRecords(list);
		return page;
	}

	@Override
	public Map<String, Object> elevatorList(PlanAffairDTO planAffairDTO) {
		Map<String, Object> resultMap = new HashMap<>(2);
		//1:正常,2:签到定位异常,3:签退定位异常，4:系统代签
		Integer[] signTypes = {0, 1, 2, 3, 4};
		List<PlanAffairVO> list;
		String signSql = "";
		if (planAffairDTO.getSignTypes() != null && planAffairDTO.getSignTypes().size() > 0) {
			for (Integer signType : planAffairDTO.getSignTypes()) {
				if (signType.equals(signTypes[1])) {
					signSql = signSql + "and t8.sign_status = 1 and t8.sign_out_status = 1";
				}
				if (signType.equals(signTypes[2])) {
					signSql = signSql + "and t8.sign_status = 2";
				}
				if (signType.equals(signTypes[3])) {
					signSql = signSql + "and t8.sign_out_status = 2";
				}
				if (signType.equals(signTypes[4])) {
					signSql = signSql + "and t8.status = 2";
				}
			}
			planAffairDTO.setSignSql(signSql);
		}
		if (planAffairDTO.getTypeStatus() == MaintainPlanContentEnum.MAINTAIN_AFFAIR.getId()) {
			list = baseMapper.listBySw(null, planAffairDTO);
		} else if (planAffairDTO.getTypeStatus() == MaintainPlanContentEnum.MAINTAIN_CHECK.getId()) {
			list = baseMapper.listByZj(null, planAffairDTO);
		} else {
			list = baseMapper.listByJy(null, planAffairDTO);
		}
		List<Long> planIds = list.stream().map(PlanAffairVO::getPlanId).collect(Collectors.toList());
		if (planIds.size() > 0) {
			for (PlanAffairVO planAffairVO : list) {
				List<MaintainPlanContentUser> maintainPlanContentUsers = maintainPlanContentUserService.listUserByPlan(planAffairVO.getPlanId());
				planAffairVO.setPlanContentUserVos(maintainPlanContentUsers);
			}
		}
		if (list.size() == 0) {
			resultMap.put("total", list.size());
			resultMap.put("list", list);
			return resultMap;
		}
		List<String> dateList = list.stream().map(PlanAffairVO::getGroupDate).distinct().collect(Collectors.toList());
		Map<String, List<PlanAffairVO>> collect = list.stream().collect(Collectors.groupingBy(PlanAffairVO::getGroupDate));
		List<PlanAffairGroupVO> resultList = new ArrayList<>(16);
		for (String date : dateList) {
			PlanAffairGroupVO planAffairGroupVO = new PlanAffairGroupVO();
			planAffairGroupVO.setPlanDate(date);
			planAffairGroupVO.setDataList(collect.get(date));
			resultList.add(planAffairGroupVO);
		}
		resultMap.put("total", list.size());
		resultMap.put("list", resultList);
		return resultMap;
	}


}
